Add in-dive annotation messages#276
Merged
Merged
Conversation
Define the protocol for adding annotations during a dive and syncing them across connected clients and into the dive logfile. Data (message_formats.proto): AnnotationType (catalogue entry), Annotation (a recorded annotation), AnnotationCatalog (a catalogue snapshot), and the AnnotationSource enum. Mirrors the annotation model in Blueye Cloud; types are referenced by slug. Down, app -> drone (requests): AnnotationCtrl (control.proto) to add one; SetAnnotationCatalogReq/Rep (req_rep.proto) to push the catalogue. Up, drone -> all clients (broadcast + logged): AnnotationTel and AnnotationCatalogTel (telemetry.proto). The drone echoes a client's AnnotationCtrl as an AnnotationTel to every connected client and writes it to the dive logfile, so clients converge and the log is self-describing; the drone can also originate an AnnotationTel itself. Late joiners fetch the latest via GetTelemetryReq by message name. Additive and backward-compatible; no new imports. VersionPrefix left untouched (protocol version tracks the BlueyeApp version and is bumped with it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds new protobuf message definitions to support “in-dive annotations”: clients can request an annotation during a dive, the drone broadcasts/logs the authoritative annotation event, and the active annotation-type catalog can be pushed and logged so the logfile remains self-describing.
Changes:
- Introduces
AnnotationSource,AnnotationType,Annotation, andAnnotationCatalogdata models inmessage_formats.proto. - Adds a fire-and-forget control message
AnnotationCtrl(app → drone) to request recording an annotation. - Adds
AnnotationTelandAnnotationCatalogTeltelemetry messages (drone → clients) plusSetAnnotationCatalogReq/Rep(app → drone) for catalog synchronization.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| protobuf_definitions/message_formats.proto | Adds core annotation data types and the AnnotationSource enum. |
| protobuf_definitions/control.proto | Adds AnnotationCtrl for requesting in-dive annotation creation. |
| protobuf_definitions/telemetry.proto | Adds AnnotationTel and AnnotationCatalogTel for broadcast/logged annotation events and catalog snapshots. |
| protobuf_definitions/req_rep.proto | Adds SetAnnotationCatalogReq/Rep for pushing the active annotation-type catalog to the drone. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Document, per review feedback, that the app sets source = APP and the drone sets DRONE for its own annotations, and that CLOUD is the post-dive cloud path not seen on the live drone telemetry path. Documentation only — source remains an informational provenance hint, intentionally not enforced (this is a first-party, non-adversarial protocol). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make each Annotation self-cohesive — it now carries the type's display fields
(type_name, type_icon, type_color) inline alongside type_slug — so the drone,
connected clients, and the dive logfile can render it without a separate
catalogue. The app keeps the full catalogue locally (synced from Blueye Cloud)
to drive its palette; only complete annotations go over the wire. type_slug is
kept so Blueye Cloud can correlate the annotation to its type on import.
Removes AnnotationType and AnnotationCatalog (message_formats.proto),
SetAnnotationCatalogReq/Rep (req_rep.proto), and AnnotationCatalogTel
(telemetry.proto). No catalogue push or ordering dependency; late joiners get a
fully self-renderable annotation from GetTelemetryReq("AnnotationTel").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per review: colour -> color (matches the color/type_color field names), catalogue -> catalog, and "cloud" -> "Cloud" to match the file's "Blueye Cloud" usage. Comments only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jp-pino
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the protocol for in-dive annotations: during a dive a diver (or any connected client) taps an annotation type in the app's command palette, and the annotation is broadcast to every connected client and recorded into the dive logfile. Part of the Blueye Cloud in-dive annotations feature.
Annotations are self-contained — each one carries the type's display fields (
type_name,type_icon,type_color) inline, so the drone, connected clients, and the dive logfile can render it with no separate catalogue. The app keeps the full annotation-type catalogue locally (synced from Blueye Cloud) to drive its palette; only complete annotations go over the wire.type_slugis kept so Blueye Cloud can correlate the annotation back to its type on import.Messages
message_formats.protoAnnotationSourceenum —CLOUD/APP/DRONE.Annotation— a self-contained annotation:type_slug,type_name,type_icon,type_color,title,body,duration,source.control.proto— app → drone (request)AnnotationCtrl— request to add an annotation. Fire-and-forget, likeLightsCtrl.telemetry.proto— drone → all clients (authoritative, broadcast, logged)AnnotationTel— the annotation that now exists on the dive. The drone echoes a client'sAnnotationCtrlhere to every connected client (so clients converge), can also originate one itself (source = DRONE), and writes it to the logfile.Design notes
.bez/ downstream tooling can render an annotation without a second lookup; a late joiner'sGetTelemetryReq("AnnotationTel")returns something fully renderable. Captures point-in-time appearance, so renaming a type in Cloud later doesn't retro-mutate old dives.type_slugfor correlation — kept so Blueye Cloud links the annotation to itsAnnotationTyperow on import (grouping, "show all Hazards"); empty for a free-form annotation.AnnotationTelit gets back, not from its ownCtrl, so multiple connected clients converge (client 1 adds → client 2 sees it).Annotation— the enclosingBinlogRecordcarries the time, like every other logged sample.sourceis an informational provenance hint, not a security claim — intentionally not enforced (first-party, non-adversarial protocol); the app setsAPP, the drone setsDRONE. See review thread replies.Open question for review
AnnotationTelis a discrete event, not periodic state. This telemetry plane is built around publish/log frequency (SetPubFrequencyReq/SetLogFrequencyReq, in Hz). Please confirm the bus can publish/log it on-change, once per event — i.e. every annotation is delivered to subscribers and written to the logfile, with no rate-based sampling that could merge two quick annotations or drop one.Validation
protoccompiles all protos together (syntax + cross-refs resolve). ✓max_line_length). ✓VersionPrefixintentionally not bumped — the protocol version tracks the BlueyeApp version and is bumped together with the app.Not in this PR
.bezparser that reconstructs annotation rows fromAnnotationTelrecords (correlating bytype_slug, falling back to the inlined display fields for free-form annotations).🤖 Generated with Claude Code